// GameController.java
package org.zjx.core.controller;

import org.zjx.core.*;
import org.zjx.core.actions.*;
import org.zjx.core.builder.DecisionTreeBuilder;
import org.zjx.core.model.InterruptEvent;
import org.zjx.core.nodes.*;
import org.zjx.core.router.StateRouter;
import org.zjx.core.state.StateAccessor;
import org.zjx.core.state.StateComponent;
import org.zjx.core.state.StateValidator;
import org.zjx.core.state.domain.*;
import org.zjx.util.DecisionUtils;

import java.time.Instant;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiPredicate;

/**
 * 游戏控制器实现
 */
public class GameController extends AbstractController {
    public GameController() {
        super(createStateValidator(),createStateAccessor());
    }


    public static StateAccessor createStateAccessor() {
        // 使用 ConcurrentHashMap 保证线程安全，键为 Class 对象，值为 StateComponent 实例
        Map<Class<? extends StateComponent>, StateComponent> stateComponents = new ConcurrentHashMap<>();

        return new StateAccessor() {
            @Override
            public <T extends StateComponent> Optional<T> getComponent(Class<T> type) {
                // 从映射中获取组件并进行类型安全的转换
                StateComponent component = stateComponents.get(type);
                if (type.isInstance(component)) {
                    return Optional.of(type.cast(component));
                }
                return Optional.empty();
            }

            @Override
            public Collection<StateComponent> getAllComponents() {
                // 返回不可修改的集合视图以保证安全性
                return Collections.unmodifiableCollection(stateComponents.values());
            }

            // 可选：添加一个方法来注册组件
            public <T extends StateComponent> void registerComponent(Class<T> type, T component) {
                stateComponents.put(type, component);
            }

            @Override
            public <T extends StateComponent> void removeComponent(Class<T> type) {
                stateComponents.remove(type);
            }
        };
    }

    @Override
    protected DecisionTree buildDomainDecisionTree() {
        return new DefaultDecisionTree(
                DecisionUtils.sequence(
                        // 检查战斗状态
                        DecisionUtils.ifThenElse(
                                ctx -> ctx.getComponent(BattleState.class)
                                        .map(b -> b.getRoundCount() > 10)
                                        .orElse(false),
                                new ActionNode(new EndBattleAction(), null),
                                // 默认决策流程
                                new StateRouter()
                                        .withState(BattleState.class, buildBattleTree())
                                        .withState(PlayerState.class, buildPlayerTree())
                        )
                ));
    }

    @Override
    protected void registerDomainInterrupts() {
        // 注册低血量中断
        interruptManager.register(InterruptEvent.createWithAccessorCondition(
                InterruptEvent.Priority.HIGH,
                "low_hp",
                () -> new ActionNode(new UsePotionAction(), null),
                (accessor, params) -> accessor.getComponent(PlayerState.class)
                        .map(p -> p.getHp() < 30)
                        .orElse(false),1000
        ));
    }


    private DecisionTree buildBattleTree() {
        return new DefaultDecisionTree(
                new DecisionTreeBuilder()
                        .when((snapshot, params) ->
                                snapshot.getComponent(BattleState.class)
                                        .map(BattleState::isTimeout)
                                        .orElse(false))
                        .action(new UltimateSkillAction())  // 使用action快捷方法
                        .endCondition()
                        .action(new NextRoundAction())
                        .build()
        );
    }

    private DecisionTree buildPlayerTree() {
        return new DefaultDecisionTree(
                new DecisionTreeBuilder()
                        .ifThenElse(
                                (accessor, params) -> accessor.getComponent(PlayerState.class)
                                        .map(p -> p.getEnergy() >= 100)
                                        .orElse(false),
                                new UltimateSkillAction(),
                                new BasicAttackAction()
                        ).build()
        );
    }

    private static StateValidator createStateValidator() {
        StateValidator validator = new StateValidator();
        // 添加领域规则
        validator.addDomainRule(BattleState.class, b -> b.getRoundCount() >= 0);
        validator.addDomainRule(PlayerState.class, p -> p.getHp() >= 0 && p.getHp() <= 100);
        // 添加全局规则
        validator.addGlobalRule(StateValidator.UNIQUE_COMPONENT_IDS);
        return validator;
    }
}